// Saver.cpp
#include "Saver.h"
#include <fstream>
#include <stdexcept>
#include "Item.h"
#include "Player.h"

// 保存游戏
bool Saver::saveGame(const Player& player, const std::string& filename) {
    try {
        json j;
        serializePlayer(player, j);

        std::ofstream ofs(filename);
        if (!ofs.is_open()) return false;

        ofs << std::setw(4) << j << std::endl;
        return true;
    }
    catch (...) {
        return false;
    }
}

// 加载游戏
bool Saver::loadGame(Player& player, const std::string& filename) {
    try {
        std::ifstream ifs(filename);
        if (!ifs.is_open()) return false;

        json j;
        ifs >> j;
        deserializePlayer(j, player);
        return true;
    }
    catch (...) {
        return false;
    }
}

// 序列化Player
void Saver::serializePlayer(const Player& player, json& j) {
    j["name"] = player.getName();
    j["level"] = player.getLevel();
    j["maxHealth"] = player.getMaxHealth();
    j["currentHealth"] = player.getCurrentHealth();
    j["maxMana"] = player.getMaxMana();
    j["currentMana"] = player.getCurrentMana();
    j["strength"] = player.getStrength();
    j["agility"] = player.getAgility();
    j["defense"] = player.getDefense();
    j["luck"] = player.getLuck();
    j["wisdom"] = player.getWisdom();
    j["accuracy"] = player.getAccuracy();
    j["dodging"] = player.getDodging();
    j["money"] = player.getMoney();
    j["expoints"] = player.getExpoints();
    j["reamount"] = player.getReamount();
    j["san"] = player.getSan();
    j["sanSpeed"] = player.getSanSpeed();

    // 序列化状态效果
    serializeStatusEffects(player.getStatusEffects(), j["status_effects"]);

    // 序列化技能
    serializeSkills(player.getSkills(), j["skills"]);

    // 序列化背包（假设Player有getBackpack()方法）
    // serializeBackpack(player.getBackpack(), j["backpack"]);
}

// 序列化状态效果
void Saver::serializeStatusEffects(const std::vector<StatusEffect>& effects, json& j) {
    for (const auto& effect : effects) {
        json effectJ;
        effectJ["type"] = static_cast<int>(effect.type);
        effectJ["duration"] = effect.duration;
        effectJ["potency"] = effect.potency;
        j.push_back(effectJ);
    }
}

// 序列化技能
void Saver::serializeSkills(const std::vector<Skill>& skills, json& j) {
    for (const auto& skill : skills) {
        json skillJ;
        skillJ["name"] = skill.getName();
        skillJ["description"] = skill.getDescription();
        skillJ["damage"] = skill.getDamage();
        skillJ["mana_cost"] = skill.getManaCost();
        skillJ["is_offensive"] = skill.isOffensiveSkill();
        skillJ["effect_type"] = static_cast<int>(skill.getEffect()); // 若effect是protected，需给Skill添加getter
        skillJ["effect_chance"] = skill.getEffectChance();
        skillJ["effect_potency"] = skill.getEffectPotency();
        j.push_back(skillJ);
    }
}

// 序列化背包
void Saver::serializeBackpack(const BackPack& backpack, json& j) {
    j["max_capacity"] = backpack.getMaxCapacity();
    j["current_count"] = backpack.getCurrentCount();

    json itemsJ;
    for (int i = 0; i < backpack.getCurrentCount(); ++i) {
        const Item* item = backpack.getItemByIndex(i); // 调用const版本
        if (item) {
            json itemJ;
            serializeItem(const_cast<Item*>(item), itemJ); // 注意：若serializeItem不修改item，可改为接收const指针
            itemsJ.push_back(itemJ);
        }
    }
    j["items"] = itemsJ;
}

// 序列化物品
void Saver::serializeItem(Item* item, json& j) {
    if (!item) return;

    // 识别物品类型
    if (dynamic_cast<Equipment*>(item)) {
        j["type"] = "equipment";
        serializeEquipment(dynamic_cast<Equipment*>(item), j);
    }
    else if (dynamic_cast<Drug*>(item)) {
        Drug* drug = dynamic_cast<Drug*>(item);
        j["type"] = "drug";
        j["name"] = item->getName();
        j["value"] = item->getValue();
        j["type"] = drug->getType();
        j["resilience"] = drug->getResilience();
    }
    else if (dynamic_cast<Special*>(item)) {
        Special* special = dynamic_cast<Special*>(item);
        j["type"] = "special";
        j["name"] = item->getName();
        j["purpose"] = special->getPurpose();
        j["isConsumable"] = special->getIsConsumable();
        j["isUsed"] = special->getIsUsed();
    }

    // 基础物品属性
    j["name"] = item->getName();
    j["value"] = item->getValue();
    j["san"] = item->getSan();
    j["power"] = item->getPower();
    j["movePower"] = item->getMovePower();
    j["wisdom"] = item->getWisdom();
    j["accuracy"] = item->getAccuracy();
    j["luck"] = item->getLuck();
    j["hitPoints"] = item->getHitPoints();
    j["armor"] = item->getArmor();
}

// 序列化装备
void Saver::serializeEquipment(Equipment* equip, json& j) {
    if (!equip) return;
    j["consume"] = equip->getConsume();
    j["slot"] = static_cast<int>(equip->getSlot());
}

// 反序列化Player
void Saver::deserializePlayer(const json& j, Player& player) {
    // 重置玩家状态（假设Player有重置方法）
    // player.reset();

    player.setName(j["name"]);
    // 基础属性赋值
    player.setMaxHealth(j["maxHealth"] - player.getMaxHealth());
    player.heal(j["currentHealth"] - player.getCurrentHealth());
    player.setMaxMana(j["maxMana"] - player.getMaxMana());
    player.restoreMana(j["currentMana"] - player.getCurrentMana());
    player.setStrength(j["strength"] - player.getStrength());
    player.setAgility(j["agility"] - player.getAgility());
    player.setDefense(j["defense"] - player.getDefense());
    player.setLuck(j["luck"] - player.getLuck());
    player.setWisdom(j["wisdom"] - player.getWisdom());
    player.setAccuracy(j["accuracy"] - player.getAccuracy());
    player.setDodging(j["dodging"] - player.getDodging());

    // 其他属性
    // 这里需要Player类提供设置金钱、经验等的方法
    player.setExpoints(j["expoints"] - player.getExpoints());
    player.setSan(j["san"] - player.getSan());
    player.setSanSpeed(j["sanSpeed"]);

    // 反序列化状态效果
    deserializeStatusEffects(j["statusEffects"], player.getStatusEffects());

    // 反序列化技能
    deserializeSkills(j["skills"], player.getSkills());

    // 反序列化背包
    // BackPack backpack(j["backpack"]["maxCapacity"]);
    // deserializeBackpack(j["backpack"], backpack);
    // player.setBackpack(backpack);
}

// 反序列化状态效果
void Saver::deserializeStatusEffects(const json& j, std::vector<StatusEffect>& effects) {
    effects.clear();
    for (const auto& e : j) {
        StatusEffect effect(
            static_cast<StatusEffect::Type>(e["type"]),
            e["duration"],
            e["potency"]
        );
        effects.push_back(effect);
    }
}

// 反序列化技能
void Saver::deserializeSkills(const json& j, std::vector<Skill>& skills) {
    skills.clear();
    for (const auto& s : j) {
        Skill skill(
            s["name"],
            s["description"],
            s["damage"],
            s["manaCost"],
            s["isOffensive"],
            StatusEffect::NONE, // 需要补充技能效果的反序列化
            0,
            0
        );
        skills.push_back(skill);
    }
}

// 反序列化背包
void Saver::deserializeBackpack(const json& j, BackPack& backpack) {
    for (const auto& itemJson : j["items"]) {
        Item* item = deserializeItem(itemJson);
        if (item) {
            backpack.addItem(item);
        }
    }
}

// 反序列化物品
Item* Saver::deserializeItem(const json& j) {
    std::string type = j["type"];

    if (type == "equipment") {
        Equipment* equip = new Equipment();
        // 基础属性
        equip->setName(j["name"]);
        equip->setValue(j["value"]);
        equip->setSan(j["san"]);
        equip->setPower(j["power"]);
        equip->setMovePower(j["movePower"]);
        equip->setWisdom(j["wisdom"]);
        equip->setAccuracy(j["accuracy"]);
        equip->setLuck(j["luck"]);
        equip->setHitPoints(j["hitPoints"]);
        equip->setArmor(j["armor"]);
        // 装备特有属性
        equip->setSlot(static_cast<EquipSlot>(j["slot"]));
        return equip;
    }
    else if (type == "drug") {
        return new Drug(
            j["name"],           // 名称
            j["value"],          // 价值
            j["drug_type"].get<char>(), // 类型（'H'/'S'/'M'）
            j["resilience"]      // 恢复力
        );
    }
    else if (type == "special") {
        return new Special(
            j["name"],
            j["purpose"],
            j["isConsumable"]
        );
    }

    return nullptr;
}

// 反序列化装备
Equipment* Saver::deserializeEquipment(const json& j) {
    Equipment* equip = new Equipment();
    // 实现装备特有属性的反序列化
    return equip;
}
